package com.itouch.widget;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Scroller;
import android.widget.TextView;

import com.itouch.bracelet.R;
import com.nostra13.universalimageloader.core.ImageLoader;

public class MyListView extends ListView implements OnScrollListener {
	private View headView;
	private int headViewHeight;
	int currentScrollState;
	private float lastDownY;
	private int deltaCount;
	private ArrayList<String> data;
	private int currentState;
	private final int DECREASE_HEADVIEW_PADDING = 100;
	private final int LOAD_DATA = 101;
	private final int DISMISS_CIRCLE = 102;
	private ImageView circle;

	private int CircleMarginTop;
	
	private String name;
	private String logo;

	private int firstVisibleItem;
	private startRefresh fresh;
	
	
	private boolean mIsFooterReady = false;
	private XListViewFooter mFooterView;
	private boolean mEnablePullLoad=true;
	private boolean mPullLoading;
	private Scroller mScroller; // used for scroll back
	// total list items, used to detect is at the bottom of listview.
	private int mTotalItemCount;
	
	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case DECREASE_HEADVIEW_PADDING:
				setHeadViewPaddingTop(deltaCount);
				setCircleMargin();
				break;
			case LOAD_DATA:
				// clearCircleViewMarginTop();
				Thread thread = new Thread(new DismissCircleThread());
				thread.start();
				currentState = LoadState.LOADSTATE_IDLE;
				break;
			case DISMISS_CIRCLE:
				int margin = msg.arg1;
				setCircleMargin(margin);
				if (margin == 0) {
					CircleAnimation.stopRotateAnmiation(circle);
				}
				break;

			}
		}

	};

	protected void setCircleMargin(int margin) {
		MarginLayoutParams lp = (MarginLayoutParams) circle.getLayoutParams();
		lp.topMargin = margin;
		circle.setLayoutParams(lp);
	}

	protected void setCircleMargin() {
		// TODO Auto-generated method stub
		MarginLayoutParams lp = (MarginLayoutParams) circle.getLayoutParams();
		lp.topMargin = CircleMarginTop - headView.getPaddingTop();
		circle.setLayoutParams(lp);
	}

	private class DecreaseThread implements Runnable {
		private final static int TIME = 25;
		private int decrease_length;

		public DecreaseThread(int count) {
			decrease_length = count / TIME;
		}

		@Override
		public void run() {
			for (int i = 0; i < TIME; i++) {
				if (i == 24) {
					deltaCount = 0;
				} else {
					deltaCount = deltaCount - decrease_length;
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
					}
				}
				Message msg = Message.obtain();
				msg.what = DECREASE_HEADVIEW_PADDING;
				handler.sendMessage(msg);
			}
		}
	}

	

	public MyListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		initHeadView(context);
	}

	public MyListView(Context context,startRefresh refresh,String nam,String log) {
		super(context);
		// TODO Auto-generated constructor stub
		fresh=refresh;
		this.name=nam;
		if(log==null||log.equals("")){
			this.logo="drawable://" + R.drawable.m_default_avatar;
		}else{
			this.logo=log;
		}
		initHeadView(context);
		mFooterView = new XListViewFooter(context);
		mFooterView.hide();
		mScroller = new Scroller(context, new DecelerateInterpolator());
				
	}

	public MyListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		initHeadView(context);
	}

	private void initHeadView(Context context) {
		headView = LayoutInflater.from(context).inflate(R.layout.header, null);
		TextView na=(TextView) headView.findViewById(R.id.textView1);
		ImageView lo=(ImageView) headView.findViewById(R.id.imageView2);
		ImageLoader.getInstance().displayImage(logo, lo);
		na.setText(name);
		lo.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				fresh.logoClick();
			}
		});
		addHeaderView(headView);
		circle = (ImageView) headView.findViewById(R.id.circleprogress);
		headView.getViewTreeObserver().addOnPreDrawListener(
				new OnPreDrawListener() {
					@Override
					public boolean onPreDraw() {
						if (headView.getMeasuredHeight() > 0) {
							headViewHeight = headView.getMeasuredHeight();
							headView.getViewTreeObserver()
									.removeOnPreDrawListener(this);
						}
						return true;
					}
				});
		setOnScrollListener(this);
		currentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
		currentState = LoadState.LOADSTATE_IDLE;
		firstVisibleItem = 0;
		CircleMarginTop = 90;
		setSelector(new ColorDrawable(Color.TRANSPARENT));
	    setItemsCanFocus(true);
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		float downY = ev.getY();
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			lastDownY = downY;
			break;
		}
		return super.dispatchTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		float downY = event.getY();
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			if (deltaCount > 0 && currentState != LoadState.LOADSTATE_LOADING
					&& firstVisibleItem == 0
					&& headView.getBottom() >= headViewHeight) {
				decreasePadding(deltaCount);
				
				fresh.loadData();
				
				startCircleAnimation();
			}
			break;
		case MotionEvent.ACTION_MOVE:
			int nowDeltaCount = (int) ((downY - lastDownY) / 3.0);
			int grepDegree = nowDeltaCount - deltaCount;
			deltaCount = nowDeltaCount;
			if (deltaCount > 0 && currentState != LoadState.LOADSTATE_LOADING
					&& firstVisibleItem == 0
					&& headView.getBottom() >= headViewHeight) {
				setHeadViewPaddingTop(deltaCount);
				setCircleViewStay();
				CircleAnimation.startCWAnimation(circle,
						5 * (deltaCount - grepDegree), 5 * deltaCount);
			}
			break;
		default:
			if (getLastVisiblePosition() == mTotalItemCount-1) {
				if (mEnablePullLoad
						&& mFooterView.getBottomMargin() == 0) {
					startLoadMore();
				}
				resetFooterHeight();
			}
			break;
				
		}

		return super.onTouchEvent(event);
	}

	public void startCircleAnimation() {
		// TODO Auto-generated method stub
		CircleAnimation.startRotateAnimation(circle);

	}

	private class DismissCircleThread implements Runnable {
		private final int COUNT = 10;
		private final int deltaMargin;

		public DismissCircleThread() {
			deltaMargin = CircleMarginTop / COUNT;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			int temp = 0;
			for (int i = 0; i <= COUNT; i++) {
				if (i == 10) {
					temp = 0;
				} else {
					temp = CircleMarginTop - deltaMargin * i;
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
					}
				}
				Message msg = Message.obtain();
				msg.what = DISMISS_CIRCLE;
				msg.arg1 = temp;
				handler.sendMessage(msg);
			}

		}
	}

	private void setCircleViewStay() {
		// TODO Auto-generated method stub
		if (headView.getPaddingTop() > (CircleMarginTop)) {
			MarginLayoutParams lp = (MarginLayoutParams) circle
					.getLayoutParams();
			lp.topMargin = CircleMarginTop - headView.getPaddingTop();
			circle.setLayoutParams(lp);
		}
	}


	

	private void setHeadViewPaddingTop(int deltaY) {
		headView.setPadding(0, deltaY, 0, 0);
	}

	private void decreasePadding(int count) {
		Thread thread = new Thread(new DecreaseThread(count));
		thread.start();
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		// TODO Auto-generated method stub
		// System.out.println(headView.getHeight());
		mTotalItemCount = totalItemCount;
		this.firstVisibleItem = firstVisibleItem;
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// TODO Auto-generated method stub

		switch (scrollState) {
		case SCROLL_STATE_FLING:
			currentScrollState = SCROLL_STATE_FLING;
			break;
		case SCROLL_STATE_IDLE:
			currentScrollState = SCROLL_STATE_IDLE;
			break;
		case SCROLL_STATE_TOUCH_SCROLL:
			currentScrollState = SCROLL_STATE_TOUCH_SCROLL;
			break;

		}

	}
	

	@Override
	public void setAdapter(ListAdapter adapter) {
		// TODO Auto-generated method stub
		if (mIsFooterReady == false) {
			mIsFooterReady = true;
			addFooterView(mFooterView);
		}
		super.setAdapter(adapter);
	}
	
	
	/**
	 * enable or disable pull up load more feature.
	 * 
	 * @param enable
	 */
	public void setPullLoadEnable(boolean enable) {
		mEnablePullLoad = enable;
		if (!mEnablePullLoad) {
			mFooterView.hide();
			mFooterView.setOnClickListener(null);
		} else {
			mPullLoading = false;
			mFooterView.show();
			mFooterView.setState(XListViewFooter.STATE_NORMAL);
			// both "pull up" and "click" will invoke load more.
			mFooterView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					startLoadMore();
				}
			});
		}
	}
	
	
	private void startLoadMore() {
		mPullLoading = true;
		mFooterView.setState(XListViewFooter.STATE_LOADING);
		fresh.loadMore();
	}
	
	private void resetFooterHeight() {
		int bottomMargin = mFooterView.getBottomMargin();
		if (bottomMargin > 0) {
			mScroller.startScroll(0, bottomMargin, 0, -bottomMargin,
					400);
			invalidate();
		}
	}
	
	
	/**
	 * 停止刷新，public方法
	 * hcx
	 */
	public void stopRefresh(){
		Message msg = Message.obtain();
		msg.what = LOAD_DATA;
		handler.sendMessage(msg);
	}
	
	public void stopLoadMore(){
		if (mPullLoading == true) {
			mPullLoading = false;
			mFooterView.setState(XListViewFooter.STATE_NORMAL);
		}
	}
	
	
	/**
	 * 供外部回调接口
	 * hcx
	 */
	public interface startRefresh{
		//刷新数据
		public void loadData();
		//点击头像（之前没考虑到，现在就放这个接口里面）
		public void logoClick();
		//载入更多
		public void loadMore();
		
	}



	
}
